﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Web.Mvc;
using System.ServiceModel.Web;
using System.Web.Http;
using System.Net.Http;
using System.Runtime.Serialization;

using ERPStore.Web.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Controllers
{
	/// <summary>
	/// WebApi REST pour la gestion de l'affichage du catalogue des produits.
	/// </summary>
	public class CatalogApiController : ApiController
	{
		[DataContract]
		public class AutocompleteLabelValue
		{
			[DataMember]
			public string label { get; set; }
			[DataMember]
			public string value { get; set; }
			[DataMember]
			public string productcode { get; set; }
		}

		public CatalogApiController(ERPStore.Services.ICatalogService catalogService
			, ERPStore.Services.IOffersService offerService)
		{
			this.CatalogService = catalogService;
			this.OfferService = offerService;
		}

		protected ERPStore.Services.ICatalogService CatalogService { get; private set; }
		protected ERPStore.Services.IOffersService OfferService { get; private set; }

		/// <summary>
		/// Retourne la date en cours du serveur (permet de tester son service)
		/// </summary>
		/// <returns>Date du serveur</returns>
		[System.Web.Http.HttpGet]
		public DateTime Ping()
		{
			return DateTime.Now;
		}

		/// <summary>
		/// Remplissage en autocompletion d'une boite de recherche avec le début de mots clés
		/// </summary>
		/// <param name="id">Keywords</param>
		/// <returns>List of autocompletlabelvalue</returns>
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public IEnumerable<AutocompleteLabelValue> Autocomplete(string id)
		{
			if (id.IsNullOrEmpty())
			{
				return null;
			}
			var list = CatalogService.GetAutocompleteSearch(id, 15);
			var result = from data in list
						 select new AutocompleteLabelValue()
						 {
							 label = "[" + data.Value + "] " + data.Key,
							 value = data.Key,
							 productcode = data.Value,
						 };

			return result;
		}

		/// <summary>
		/// Retourne la liste de toutes les categories de produit actives
		/// </summary>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public IEnumerable<ERPStore.Models.ProductCategory> GetProductCategoryList()
		{
			var result = CatalogService.GetCategories();
			foreach (var item in result)
			{
				// item.Children.Clear();
			}
			return result.OrderBy(i => i.FrontOrder.GetValueOrDefault(int.MaxValue));
		}

		/// <summary>
		/// Retourne une liste de categorie contrainte par un filtre de cherche
		/// </summary>
		/// <param name="filter">ProductListFilter</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public IEnumerable<ERPStore.Models.ProductCategory> GetProductCategoryListByFilter(ERPStore.Models.ProductListFilter filter)
		{
			if (filter == null)
			{
				return null;
			}
			var result = CatalogService.GetProductCategoryListBySearch(filter);
			if (filter.ProductCategoryId.HasValue
				&& result.IsNotNullOrEmpty()
				&& result.Count == 1)
			{
				result = result[0].Children;
			}
			foreach (var item in result)
			{
				// item.Children.Clear();
			}
			return result;
		}

		/// <summary>
		/// Retourne une categorie de produit via son code
		/// </summary>
		/// <param name="id">Code de la categorie</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public ERPStore.Models.ProductCategory GetProductCategoryByCode(string id)
		{
			if (id.IsNullOrTrimmedEmpty())
			{
				return null;
			}
			var result = CatalogService.GetCategoryByCode(id);
			return result;
		}

		/// <summary>
		/// Retourne la liste complete des marques actives
		/// </summary>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public IEnumerable<ERPStore.Models.Brand> GetBrandList()
		{
			return CatalogService.GetBrands();
		}

		/// <summary>
		/// Retourne la liste des marques contrainte par un filtre
		/// </summary>
		/// <param name="filter">ProductListFilter</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public IEnumerable<ERPStore.Models.Brand> GetBrandListByFilter(ERPStore.Models.ProductListFilter filter)
		{
			if (filter == null)
			{
				return null;
			}
			return CatalogService.GetBrandListBySearch(filter);
		}

		/// <summary>
		/// Retourne la liste des marques de la page d'accueil
		/// </summary>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public IEnumerable<ERPStore.Models.Brand> GetBrandListForeFront()
		{
			return CatalogService.GetBrandListForefront();
		}

		/// <summary>
		/// Retourne une marque via son nom
		/// </summary>
		/// <param name="id">Nom de la marque</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public ERPStore.Models.Brand GetBrandByName(string id)
		{
			if (id.IsNullOrTrimmedEmpty())
			{
				return null;
			}
			return CatalogService.GetBrandByName(id);
		}

		/// <summary>
		/// Retourne une catégorie de produit via son lien
		/// </summary>
		/// <param name="id">Lien de la category (voir la propriété Link)</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public ERPStore.Models.ProductCategory GetProductCategoryByLink(string id)
		{
			if (id.IsNullOrTrimmedEmpty())
			{
				return null;
			}
			var category = CatalogService.GetCategoryByLink(id);
			return category;
		}

		/// <summary>
		/// Retourne une liste des produits via un filtre
		/// </summary>
		/// <code>
		/// var filter = new ProductListFilter();
		/// filter.Search = "tournevis";
		/// filter.PageSize = 20; // Maximum 50 produits par page
		/// filter.PageIndex = 0; // Index de la page
		/// 
		/// var result = CatalogService.GetProductListByFilter(filter);
		/// 
		/// var productCount = result.ItemCount; // Retourne le nombre de produits au total
		/// var list = result.List; // Contient la liste des produits
		/// 
		/// </code>
		/// <param name="filter">ProductListFilter</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public ERPStore.Models.ProductListResult GetProductListByFilter(ERPStore.Models.ProductListFilter filter)
		{
			int count = 0;
			if (filter == null)
			{
				return null;
			}
			filter.PageSize = Math.Min(filter.PageSize, 50);
			filter.PageIndex = Math.Min(filter.PageIndex, 500);
			var list = CatalogService.GetProductListBySearch(filter, filter.PageIndex, filter.PageSize, out count);
			foreach (var product in list)
			{
				OfferService.ApplyOffers(product, null);
				PrepareToSerialize(product);
				if (product.Category != null)
				{
					// product.Category.Children.Clear();
				}
			}
			var result = new ERPStore.Models.ProductListResult();
			result.List = list.ToList();
			result.ItemCount = count;
			return result;
		}

		/// <summary>
		/// Retourne un produit via son code
		/// </summary>
		/// <param name="id">Code unique du prouduit (voir Product.Code)</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public ERPStore.Models.Product GetProductByCode(string id)
		{
			if (id.IsNullOrTrimmedEmpty())
			{
				return null;
			}
			var result = CatalogService.GetProductByCode(id);
			if (result == null)
			{
				return null;
			}
			OfferService.ApplyOffers(result, null);
			PrepareToSerialize(result);
			return result;
		}

		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public List<ERPStore.Models.Product> GetProductListByIdList([FromBody] List<int> idList)
		{
			if (!this.ControllerContext.IsAuthenticatedRequest())
			{
				return null;
			}

			if (idList.IsNullOrEmpty())
			{
				return null;
			}

			if (idList.Count > 50)
			{
				throw new Exception("too many id, 50 max");
			}

			var list = CatalogService.GetProductListByIdList(idList, false);

			var result = new List<ERPStore.Models.Product>();
			foreach (var product in list)
			{
				OfferService.ApplyOffers(product, null);
				PrepareToSerialize(product);
				result.Add(product);
			}

			return result;

		}


		/// <summary>
		/// Retourne liste de produit via une liste de code produit
		/// </summary>
		/// <param name="codeList">Liste de code produit</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public List<ERPStore.Models.Product> GetProductListByCodeList([FromBody] List<string> codeList)
		{
			if (codeList.IsNullOrEmpty())
			{
				return null;
			}

			if (codeList.Count > 50)
			{
				var httpResponse = new HttpResponseMessage(System.Net.HttpStatusCode.ExpectationFailed);
				httpResponse.Content = new StringContent("too many code, 50 max");
				throw new HttpResponseException(httpResponse);
			}

			var result = new List<ERPStore.Models.Product>();
			foreach (var code in codeList)
			{
				var product = CatalogService.GetProductByCode(code);
				if (product == null)
				{
					continue;
				}
				OfferService.ApplyOffers(product, null);
				PrepareToSerialize(product);
				result.Add(product);
			}

			return result;
		}

		/// <summary>
		/// Retourne les informations de stockage d'un produit via son code
		/// </summary>
		/// <param name="id">Code du produit (voir Product.Code)</param>
		/// <returns></returns>
		[System.Web.Http.HttpGet]
		public ERPStore.Models.ProductStockInfo GetProductStockInfoByCode(string id)
		{
			if (id.IsNullOrTrimmedEmpty())
			{
				return null;
			}
			return CatalogService.GetProductStockInfo(id);
		}

		private void PrepareToSerialize(ERPStore.Models.Product product)
		{
			if (this.ControllerContext.IsAuthenticatedRequest())
			{
				return;
			}

			if (product.Brand != null
				&& product.Brand.DefaultImage != null)
			{
				product.Brand.DefaultImage.ExternalUrl = null;
			}

			if (product.Category != null
				&& product.Category.DefaultImage != null)
			{
				product.Category.DefaultImage.ExternalUrl = null;
			}

			if (product.DefaultImage != null)
			{
				product.DefaultImage.ExternalUrl = null;
			}

			product.OrderCount = 0;

			if (product.Stats != null)
			{
				product.Stats.DistinctCustomerCount = 0;
				product.Stats.OrderCount = 0;
				product.Stats.SaleTotal = 0;
				product.Stats.VisitorCount = 0;
			}

			if (product.SelectedOffer != null)
			{
				var so = product.SelectedOffer;

				var offer = new ERPStore.Models.Offer()
				{
					CSSTag = product.SelectedOffer.CSSTag,
					Description = product.SelectedOffer.Description,
					EndDate = product.SelectedOffer.EndDate,
					Link = product.SelectedOffer.Link,
					Name = product.SelectedOffer.Name,
					PhysicalStockMandatory = product.SelectedOffer.PhysicalStockMandatory,
					StartDate = product.SelectedOffer.StartDate,
					Title = product.SelectedOffer.ViewName,
					ViewName = product.SelectedOffer.ViewName,
				};

				product.SelectedOffer = offer;
			}
			product.OfferList = null;
		}

	}
}
